import * as XLSX from "xlsx";

export interface ExcelColumn {
  title: string;
  dataIndex: string;
  key: string;
  render?: (value: any, record: any) => any;
}

export interface ExcelExportOptions {
  filename?: string;
  sheetName?: string;
  columns: ExcelColumn[];
  data: any[];
}

/**
 * 导出数据到Excel文件
 * @param options 导出配置选项
 */
export const exportToExcel = (options: ExcelExportOptions) => {
  const { filename = "导出数据", sheetName = "Sheet1", columns, data } = options;

  // 处理表头
  const headers = columns.map((col) => col.title);

  // 处理数据行
  const rows = data.map((record) => {
    return columns.map((col) => {
      const value = record[col.dataIndex];
      // 如果有自定义渲染函数，使用渲染函数处理值
      if (col.render && typeof col.render === "function") {
        const rendered = col.render(value, record);
        // 如果渲染结果是React元素或复杂对象，尝试提取文本内容
        if (typeof rendered === "object" && rendered !== null) {
          return String(rendered);
        }
        return rendered;
      }
      return value;
    });
  });

  // 合并表头和数据
  const worksheetData = [headers, ...rows];

  // 创建工作表
  const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);

  // 设置列宽（可选）
  const colWidths = columns.map(() => ({ wch: 15 }));
  worksheet["!cols"] = colWidths;

  // 创建工作簿
  const workbook = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);

  // 导出文件
  const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, "-");
  const finalFilename = `${filename}_${timestamp}.xlsx`;

  XLSX.writeFile(workbook, finalFilename);
};

/**
 * 根据选中的行导出数据
 * @param options 导出配置选项
 * @param selectedKeys 选中的行keys
 * @param keyField 用作key的字段名，默认为'id'
 */
export const exportSelectedToExcel = (
  options: Omit<ExcelExportOptions, "data">,
  allData: any[],
  selectedKeys: React.Key[],
  keyField: string = "id",
) => {
  // 过滤出选中的数据
  const selectedData = allData.filter((item) => selectedKeys.includes(item[keyField]));

  if (selectedData.length === 0) {
    return;
  }

  exportToExcel({
    ...options,
    data: selectedData,
    filename: `${options.filename || "选中数据"}_${selectedData.length}条`,
  });
};
